home *** CD-ROM | disk | FTP | other *** search
- ===========================================================================
- BBS: The Abacus * HST/DS * Potterville MI
- Date: 05-09-93 (17:49) Number: 60
- From: MATTHEW HUNT Refer#: 187
- To: THAD SMITH Recvd: NO
- Subj: GCC and % Operator Conf: (36) C Language
- ---------------------------------------------------------------------------
- Thad,
-
- Thursday May 06 1993, Thad Smith writes to Matthew Hunt:
-
- TS> It sounds like the rand() function is rotten. Post the code for rand().
-
- Gladly, although it's rather large:
-
- ===SNIP===
- /* This is file RANDOM.C */
- /* This file may have been modified by DJ Delorie (Jan 1991). If so,
- ** these modifications are Coyright (C) 1991 DJ Delorie, 24 Kirsten Ave,
- ** Rochester NH, 03867-2954, USA.
- */
-
- /*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that: (1) source distributions retain this entire copyright
- * notice and comment, and (2) distributions including binaries display
- * the following acknowledgement: ``This product includes software
- * developed by the University of California, Berkeley and its contributors''
- * in the documentation or other materials provided with the distribution
- * and in all advertising materials mentioning features or use of this
- * software. Neither the name of the University nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)random.c 5.7 (Berkeley) 6/1/90";
- #endif /* LIBC_SCCS and not lint */
-
- #include <stdio.h>
-
- /*
- * random.c:
- * An improved random number generation package. In addition to the standard
- * rand()/srand() like interface, this package also has a special state info
- * interface. The initstate() routine is called with a seed, an array of
- * bytes, and a count of how many bytes are being passed in; this array is then
- * initialized to contain information for random number generation with that
- * much state information. Good sizes for the amount of state information are
- * 32, 64, 128, and 256 bytes. The state can be switched by calling the
- * setstate() routine with the same array as was initiallized with initstate().
- * By default, the package runs with 128 bytes of state information and
- * generates far better random numbers than a linear congruential generator.
- * If the amount of state information is less than 32 bytes, a simple linear
- * congruential R.N.G. is used.
- * Internally, the state information is treated as an array of longs; the
- * zeroeth element of the array is the type of R.N.G. being used (small
- * integer); the remainder of the array is the state information for the
- * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
- * state information, which will allow a degree seven polynomial. (Note: the
- * zeroeth word of state information also has some other information stored
- * in it -- see setstate() for details).
- * The random number generation technique is a linear feedback shift register
- * approach, employing trinomials (since there are fewer terms to sum up that
- * way). In this approach, the least significant bit of all the numbers in
- * the state table will act as a linear feedback shift register, and will have
- * period 2^deg - 1 (where deg is the degree of the polynomial being used,
- * assuming that the polynomial is irreducible and primitive). The higher
- * order bits will have longer periods, since their values are also influenced
- * by pseudo-random carries out of the lower bits. The total period of the
- * generator is approximately deg*(2**deg - 1); thus doubling the amount of
- * state information has a vast influence on the period of the generator.
- * Note: the deg*(2**deg - 1) is an approximation only good for large deg,
- * when the period of the shift register is the dominant factor. With deg
- * equal to seven, the period is actually much longer than the 7*(2**7 - 1)
- * predicted by this formula.
- */
-
-
-
- /*
- * For each of the currently supported random number generators, we have a
- * break value on the amount of state information (you need at least this
- * many bytes of state info to support this random number generator), a degree
- * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
- * the separation between the two lower order coefficients of the trinomial.
- */
-
- #define TYPE_0 0 /* linear congruential */
- #define BREAK_0 8
- #define DEG_0 0
- #define SEP_0 0
-
- #define TYPE_1 1 /* x**7 + x**3 + 1 */
- #define BREAK_1 32
- #define DEG_1 7
- #define SEP_1 3
-
- #define TYPE_2 2 /* x**15 + x + 1 */
- #define BREAK_2 64
- #define DEG_2 15
- #define SEP_2 1
-
- #define TYPE_3 3 /* x**31 + x**3 + 1 */
- #define BREAK_3 128
- #define DEG_3 31
- #define SEP_3 3
-
- #define TYPE_4 4 /* x**63 + x + 1 */
- #define BREAK_4 256
- #define DEG_4 63
- #define SEP_4 1
-
-
- /*
- * Array versions of the above information to make code run faster -- relies
- * on fact that TYPE_i == i.
- */
-
- #define MAX_TYPES 5 /* max number of types above */
-
- static int degrees[ MAX_TYPES ] = { DEG_0, DEG_1, DEG_2,
- DEG_3, DEG_4 };
-
- static int seps[ MAX_TYPES ] = { SEP_0, SEP_1, SEP_2,
- SEP_3, SEP_4 };
-
-
-
- /*
- * Initially, everything is set up as if from :
- * initstate( 1, &randtbl, 128 );
- * Note that this initialization takes advantage of the fact that srandom()
- * advances the front and rear pointers 10*rand_deg times, and hence the
- * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
- * element of the state information, which contains info about the current
- * position of the rear pointer is just
- * MAX_TYPES*(rptr - state) + TYPE_3 == TYPE_3.
- */
-
- static long randtbl[ DEG_3 + 1 ] = { TYPE_3,
- 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342,
- 0xde3b81e0, 0xdf0a6fb5, 0xf103bc02, 0x48f340fb,
- 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,
- 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86,
- 0xda672e2a, 0x1588ca88, 0xe369735d, 0x904f35f7,
- 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
- 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b,
- 0xf5ad9d0e, 0x8999220b, 0x27fb47b9 };
-